package owg.util.opengl;

import com.jogamp.opengl.GL;
import com.jogamp.opengl.GL2;

/**
 * This class represents a simple material, as loaded from a wavefront mtllib.
 * I won't rule out the possibility that I have to learn to write GLSL shaders at a later time.
 */
public class Material
	{
	public String mtllib;
	public String name;
	public int index;//1-indexed!
	public ColorF ambientColor;
	public ColorF diffuseColor;
	public ColorF specularColor;
	public ColorF emitColor;
	public int specularWeight;
	public float alpha;//Not used directly
	/**If true, color multiplier defaults to white, so texture color is not scaled.*/
	public boolean textureOverride = true;
	/**If true, alpha test will be enabled for this material*/
	public boolean transparentFaces = false;
	/**If true, backface culling will be disabled*/
	public boolean doubleSided = false;
	/**If true, the texture also affects the specular highlights*/
	public boolean specularTexture = false;
	/*
	 * Illumination mode, not used.
	0. Color on and Ambient off
	1. Color on and Ambient on
	2. Highlight on
	3. Reflection on and Ray trace on
	4. Transparency: Glass on, Reflection: Ray trace on
	5. Reflection: Fresnel on and Ray trace on
	6. Transparency: Refraction on, Reflection: Fresnel off and Ray trace on
	7. Transparency: Refraction on, Reflection: Fresnel on and Ray trace on
	8. Reflection on and Ray trace off
	9. Transparency: Glass on, Reflection: Ray trace off
	10. Casts shadows onto invisible surfaces
	*/
	public Tex diffuseTex;//Only use diffuse texture for now.
	
	public Material(String mtllib, String name, int index)
		{
		this.mtllib = mtllib;
		this.name= name;
		this.index= index;
		this.ambientColor = ColorF.WHITE;
		this.diffuseColor = ColorF.WHITE;
		this.specularColor= ColorF.BLACK;
		this.emitColor    = ColorF.BLACK;
		this.specularWeight = 32;//openGL takes the range 0-128.
		this.diffuseTex = null;
		this.alpha=1;
		}
	
	public Material(String mtllib, String name, int index, float[] ambientColor, float[] diffuseColor, float[] specularColor, float specularWeight, float alpha, String diffuseTextureName)
		{
		this.mtllib = mtllib;
		this.name=name;
		this.index=index;
		this.ambientColor = new ColorF(ambientColor);
		this.diffuseColor = new ColorF(diffuseColor, alpha);
		this.specularColor= new ColorF(specularColor);
		this.emitColor    = new ColorF(emitColor);
		this.specularWeight = (int)(specularWeight*128/1000);//openGL takes the range 0-128.
		this.diffuseTex = TextureLib.tex(diffuseTextureName);
		this.alpha=alpha;
		}

	public void setAlpha(float alpha)
		{
		diffuseColor = new ColorF(diffuseColor,alpha);
		this.alpha=alpha;
		}
	public float getAlpha()
		{
		return alpha;
		}
	
	/**Enable the material with the given subimage for the texture, if any. Remember to disable.*/
	public void enable(EGL<?> glUtil, int texSubImage)
		{
		if(glUtil.getGL().isGL2())
			{
			GL2 gl = (GL2)glUtil.getGL();
			
			if(transparentFaces)
				gl.glEnable(GL2.GL_ALPHA_TEST);
			if(doubleSided)
				gl.glDisable(GL2.GL_CULL_FACE);
			gl.glEnable(GL2.GL_LIGHTING);
			if (!textureOverride || diffuseTex==null)
				{
			    gl.glColorMaterial(GL.GL_FRONT_AND_BACK, GL2.GL_DIFFUSE );
			    gl.glColor4fv(diffuseColor.data,0);
			    gl.glMaterialfv(GL.GL_FRONT_AND_BACK, GL2.GL_AMBIENT, ambientColor.data,0);
				}
			else
				{
				gl.glColor4f(1,1,1,alpha);
				}
	        gl.glMaterialfv(GL.GL_FRONT_AND_BACK, GL2.GL_EMISSION, emitColor.data,0);
	        gl.glMaterialfv(GL.GL_FRONT_AND_BACK, GL2.GL_SPECULAR, specularColor.data,0);
	        gl.glMateriali(GL.GL_FRONT_AND_BACK,GL2.GL_SHININESS,specularWeight);
	
			if(specularTexture)
				gl.glLightModeli(GL2.GL_LIGHT_MODEL_COLOR_CONTROL, GL2.GL_SINGLE_COLOR);
				
	        if(diffuseTex!=null)
	        	{
	        	glUtil.enableTexture2D(diffuseTex, texSubImage);
	        	}
			}
		}
	public void disable(EGL<?> glUtil)
		{
		if(glUtil.getGL().isGL2())
			{
			GL2 gl = (GL2)glUtil.getGL();
				
			if(transparentFaces)
				gl.glDisable(GL2.GL_ALPHA_TEST);
			if(doubleSided)
				gl.glEnable(GL2.GL_CULL_FACE);
			//This is important:
			if(diffuseTex!=null)
				glUtil.disableTexture2D();
			if(specularTexture)
				gl.glLightModeli(GL2.GL_LIGHT_MODEL_COLOR_CONTROL, GL2.GL_SEPARATE_SPECULAR_COLOR);
			//Reset this because it's likely that you'll want it back the way it was
			gl.glColorMaterial(GL.GL_FRONT_AND_BACK, GL2.GL_AMBIENT_AND_DIFFUSE );
			gl.glMaterialfv(GL.GL_FRONT_AND_BACK, GL2.GL_EMISSION, ColorF.BLACK.data,0);
	        gl.glMaterialfv(GL.GL_FRONT_AND_BACK, GL2.GL_SPECULAR, ColorF.BLACK.data,0);
	        gl.glMateriali(GL.GL_FRONT_AND_BACK,GL2.GL_SHININESS,32);
	        gl.glColor4fv(ColorF.WHITE.data,0);
			}
		}
	}
